<template>
    <h3>姓名：{{user.name}}</h3>
    <h3>年龄：{{user.age}}</h3>
    <h3>性别：{{user.sex}}</h3>
    <h3>爱人：{{user.wife}}</h3>
    <hr/>
    <button @click="updateUser">更新</button>
</template>

<script lang="ts">
import { defineComponent, reactive } from 'vue';

export default defineComponent({
  name: 'App',
  // 需求：显示用户的相关信息，点击按钮，可以更新用户的相关信息数据
  /**
   * reactive
   * 作用；定义多个数据的响应式
   * const proxy = reactive(obj)：接收一个普通对象然后返回该普通对象的的响应式代理器对象
   * 响应式转换是“深层的”：会影响对象内部所有嵌套的属性
   * 内部基于es6的proxy实现，通过代理对象操作源对象内部数据都是响应式的
  */
  setup() {
    //   const obj:any = { // 为了在使用obj.sex='男'不显示错误信息才这么写
        const obj = {
          name: 'xiaoming',
          age: 20,
          wife:{
              name: 'xiaohua',
              age: 18,
              cars: ['112', '233', '343']
          }
      }
      // 把复杂数据标称响应式的
      // 返回的是一个proxy的代理对象，被代理者就是obj对象
      // user 现在是代理对象，obj是目标对象
      // user对象的类型是Proxy
      const user = reactive<any>(obj)
      console.log(user)

      // 方法
      const updateUser = () => {
          // 直接使用目标对象的方式来更新目标对象中的成员的值，不可用，只能使用代理对象的方式来更新数据（响应式数据）
        //   obj.name += '===='
        //   user.name += '=='
        //   user.wife.name += '+++'
        //   user.wife.cars[0] = 'sdwdewretttt'

          // user---->代理对象，obj----->目标对象
          // user 或者obj添加一个新的属性，哪一种方式会影响界面的更新
        //  // obj.sex = '男' // 界面没有更新渲染
        user.sex = '男' // 这种方式界面可以渲染，这个数据最终也添加到了obj对象
          // user对象或者obj对象中移除一个已经存在的属性，哪一种方式会影响界面的更新
        // delete obj.age // 界面美誉更新渲染，obj中确实没有了age这个属性
        delete user.age


        // 如果操作代理对象，目标对象中的数据也会随之变化，同时如果想要在操作数据的时候，界面也要更新渲染
      }
      return {
          user,
          updateUser
      }
  }
});

</script>
